package com.yopuo.common.utils.sms;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.yopuo.common.core.redis.RedisCache;
import com.yopuo.common.utils.sms.vo.AliSmsVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @version 1.0
 * @date 2020/11/24 09:42
 * @description 阿里短信工具类 2020.8.5最新使用方式
 * @author zzh
 */
public class AliSmsUtils {
    private static final Logger log = LoggerFactory.getLogger(AliSmsUtils.class);
    /*********************************************  需要修改的部分start  *************************************************/

    /**
     * 需要替换为自己的ACCESS_KEY_ID
     */
    private static final String ACCESS_KEY_ID = "LTAIalwvInx7UX2o";

    /**
     * 需要替换为自己的ACCESS_KEY_SECRET
     */
    private static final String ACCESS_KEY_SECRET = "qD5v6MNoBBDjNksHAjqrM9dipZ54K3";

    /**
     * 这里要修改为自己的短信签名
     */
//    private static final String SIGN_NAME = "浙江天能优品网络科技有限公司";
    private static final String SIGN_NAME = "周志骅";

    /*********************************************  需要修改的部分end  *************************************************/

    /**
     * 下面是一些默认的配置，无需修改
     * REGION_ID 服务器大区   不建议修改
     * SYS_DOMAIN API地址   不可修改
     * SYS_VERSION 系统版本 不可修改
     * SYS_ACTION API接口名必须为SendSms 不可修改
     */
    private static final String REGION_ID = "cn-hangzhou";
    private static final String SYS_DOMAIN = "dysmsapi.aliyuncs.com";
    private static final String SYS_VERSION = "2017-05-25";
    private static final String SYS_ACTION = "SendSms";

    /**
     * 预编译正则，提高效率
     */
    private static final Pattern PATTERN = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");

    /**
     * 创建profile对象
     */
    private static DefaultProfile profile;

    /**
     * 创建client对象
     */
    private static IAcsClient client;

    /**
     * 创建request对象
     */
    private static CommonRequest request;

    /**
     * redis缓存工具类
     */
    @Resource
    private static RedisCache redisCache;

    /**
     * 静态代码块中初始化一些参数
     */
    static {
        //初始化profile
        profile = DefaultProfile.getProfile(REGION_ID, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        client = new DefaultAcsClient(profile);

        //初始化一些参数
        request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain(SYS_DOMAIN);
        request.setSysVersion(SYS_VERSION);
        request.setSysAction(SYS_ACTION);
        request.putQueryParameter("RegionId", REGION_ID);
        request.putQueryParameter("SignName", SIGN_NAME);
    }

    /**
     * 校验手机号是否合法
     * @param phoneNumber
     * @return
     */
    public static boolean isPhoneNumber(String phoneNumber) {
        Matcher m = PATTERN.matcher(phoneNumber);
        return m.matches();
    }


    /**
     * 发送自定义短信的逻辑
     * @param phoneNumber 手机号码
     * @param templateCode 短信模板编码，在阿里云短信服务配置
     * @param templateParams 短信自定义参数 json格式 {"code":"1111","name":"2222"}
     * @return AliSmsVo
     */
    public static AliSmsVo sendMessage(String phoneNumber, String templateParams, String templateCode) {

        //创建result
        return sendAliSmsBase(phoneNumber, templateCode, templateParams);
    }

    /**
     * 发送验证码短信的逻辑
     * @param phoneNumber 手机号码
     * @param templateCode 短信模板编码，在阿里云短信服务配置
     * @return AliSmsVo
     */
    public static AliSmsVo sendCodeMessage(String phoneNumber, String templateCode) {
        //获取六位随机数
        String code = (long) (Math.random() * (999999 - 100000) + 100000) + "";
        HashMap<String, String> map = new HashMap<>(1);
        map.put("code",code);
        String templateParams = JSONObject.toJSONString(map);
        AliSmsVo result = sendAliSmsBase(phoneNumber, templateCode, templateParams);
        //验证码放入缓存，过期时间：5分钟
        if (result.isSuccess()){
            redisCache.setCacheObject(phoneNumber.concat("code"),code,5, TimeUnit.MINUTES);
        }
        return result;

    }

    private static AliSmsVo sendAliSmsBase(String phoneNumber, String templateCode, String templateParams) {
        //创建result
        AliSmsVo result = new AliSmsVo();
        //默认为false，只有成功时为true
        result.setSuccess(false);
        //判断是否为手机号
        if (!isPhoneNumber(phoneNumber)) {
            result.setMsg("手机号码不合法！" );
            return result;
        }
        //初始化短信模板编码
        request.putQueryParameter("TemplateCode" , templateCode);
        //初始化用户自定义参数
        request.putQueryParameter("PhoneNumbers" , phoneNumber);
        //在短信内容中嵌入随机数
        request.putQueryParameter("TemplateParam" , templateParams);

        //发送的业务逻辑
        try {
            client.getCommonResponse(request);
        } catch (Exception e) {
            log.error("{}发送短信失败，请查看错误信息：{}" , phoneNumber, e.getMessage());
            result.setMsg(phoneNumber + "发送短信失败，请查看错误信息：" + e.getMessage());
            return result;
        }
        //成功则返回正确的信息
        result.setMsg("短信发送成功！" );
        result.setSuccess(true);
        return result;
    }

    /**
     * 私有化构造
     */
    private AliSmsUtils() {}

    public static void main(String[] args) {
        String templateCode = "SMS_77470009";
        //获取六位随机数
        String code = (long) (Math.random() * (999999 - 100000) + 100000) + "";
        HashMap<String, String> map = new HashMap<>(2);
        map.put("name","骅哥");
        map.put("number",code);
        String toJSONString = JSONObject.toJSONString(map);
        AliSmsVo aliSmsVo = AliSmsUtils.sendMessage("18705725703", toJSONString, templateCode);
        System.out.println("结果：" + aliSmsVo.getMsg());

    }
}